/**
 * @file usb_com.c
 * @author Jae Frank (thissfk@qq.com)
 * @brief 
 * @version 0.1
 * @date 2024-01-16
 * 
 * @copyright Copyright (c) 2024
 * 
 */
#include "usb_com.h"

HANDLE OpenSerial(const char *com, //串口名称，如COM1，COM2
                  int baud,        //波特率：常用取值：CBR_9600、CBR_19200、CBR_38400、CBR_115200、CBR_230400、CBR_460800
                  int byteSize,    //数位大小：可取值7、8；
                  int parity,      //校验方式：可取值NOPARITY、ODDPARITY、EVENPARITY、MARKPARITY、SPACEPARITY
                  int stopBits)    //停止位：ONESTOPBIT、ONE5STOPBITS、TWOSTOPBITS；
{
    DCB dcb;
    BOOL b = FALSE;
    COMMTIMEOUTS CommTimeouts;
    HANDLE comHandle = INVALID_HANDLE_VALUE;

    //打开串口
    comHandle = CreateFile(com,                          //串口名称
                           GENERIC_READ | GENERIC_WRITE, //可读、可写
                           0,                            // No Sharing
                           NULL,                         // No Security
                           OPEN_EXISTING,                // Open existing port only
                           FILE_ATTRIBUTE_NORMAL,        // Non Overlapped I/O
                           NULL);                        // Null for Comm Devices

    if (INVALID_HANDLE_VALUE == comHandle)
    {
        LOGE("CreateFile fail\r\n");
        return comHandle;
    }

    // 设置读写缓存大小
    b = SetupComm(comHandle, BUF_SIZE, BUF_SIZE);
    if (!b)
    {
        LOGE("SetupComm fail\r\n");
    }

    //设定读写超时
    CommTimeouts.ReadIntervalTimeout = MAXDWORD;   //读间隔超时
    CommTimeouts.ReadTotalTimeoutMultiplier = 0;   //读时间系数
    CommTimeouts.ReadTotalTimeoutConstant = 0;     //读时间常量
    CommTimeouts.WriteTotalTimeoutMultiplier = 1;  //写时间系数
    CommTimeouts.WriteTotalTimeoutConstant = 1;    //写时间常量
    b = SetCommTimeouts(comHandle, &CommTimeouts); //设置超时
    if (!b)
    {
        LOGE("SetCommTimeouts fail\r\n");
    }

    //设置串口状态属性
    GetCommState(comHandle, &dcb);     //获取当前
    dcb.BaudRate = baud;               //波特率
    dcb.ByteSize = byteSize;           //每个字节有位数
    dcb.Parity = parity;               //无奇偶校验位
    dcb.StopBits = stopBits;           //一个停止位
    b = SetCommState(comHandle, &dcb); //设置
    if (!b)
    {
        LOGE("SetCommState fail\r\n");
    }

    return comHandle;
}

BOOL ReadSerial(HANDLE comHandle)
{
    BOOL b = FALSE,continue_bit = TRUE; 
    DWORD wRLen = 0;
    DWORD wWLen = 0;
    char buf[BUF_SIZE] = {0};

    //读串口消息
    b = ReadFile(comHandle, buf, sizeof(buf) - 1, &wRLen, NULL);
    if (b && 0 < wRLen)
    { //读成功并且数据大小大于0
        buf[wRLen] = '\0';
        LOGD("[RECV]%s\r\n", buf); //打印收到的数据
        if (0 == strncmp(buf, EXIT_STR, strlen(EXIT_STR)))
        {
            //回复
            b = WriteFile(comHandle, TEXT(I_EXIT), strlen(I_EXIT), &wWLen, NULL);
            if (!b)
            {
                LOGE("WriteFile fail\r\n");
            }
            return continue_bit = FALSE; //
        }
        //回复
        b = WriteFile(comHandle, TEXT(I_RECEIVE), strlen(I_RECEIVE), &wWLen, NULL);
        if (!b)
        {
            LOGE("WriteFile fail\r\n");
        }
    }
    return continue_bit;
}
